在 Day 2 摘要重點時有講到『 PowerShell 並不是一種指令碼語言,也不是一種程式語言,PowerShell 實際上是一種命令列 shell ( a command-line shell )。 』,因此本書第四章作者要我們學習的重點即是執行命令和使用命令列工具。
在這一小節中,我們的目標是幫助你深入了解 PowerShell 如何對環境中的安全性造成影響,並指導你調整 PowerShell,在安全性與功能性之間達到你所期望的平衡。
PowerShell 只能執行你已有權限的操作。換言之,如果你原本可以透過圖形介面新增、修改或刪除某資料夾中的檔案,那麼你也可以透過 PowerShell 執行相同的操作。正如書中所提到:
PowerShell 的安全機制不是為了限制使用者輸入或執行他們已有權限的命令。它的理念是,「欺騙使用者輸入一個冗長又複雜的命令」這件事是困難的,所以 PowerShell 不會去套用任何使用者現有以外的安全策略。
PowerShell 的執行政策是一種安全功能,用於控制 PowerShell 加載配置文件和運行腳本的條件,從而有助於防止執行惡意腳本,它規範了 PowerShell 能執行的指令碼,可透過 about_Execution_Policies 了解細節。
> get-help execution
Name Category Module Synopsis
---- -------- ------ --------
Get-ExecutionPolicy Cmdlet Microsoft.PowerShell.Sec… Gets the execution policies for the current session.
Set-ExecutionPolicy Cmdlet Microsoft.PowerShell.Sec… Sets the PowerShell execution policies for Windows computers.
about_Execution_Policies HelpFile
> get-help about_Execution_Policies | more
透過 ChatGPT 將 about_Execution_Policies 的內容裡針對 PowerShell 執行政策 及 PowerShell 執行策略範圍 整理如下:
執行政策 | 描述 | 關鍵點 |
---|---|---|
Restricted | Windows 用戶端電腦的預設執行政策。- 允許執行單一命令,但不允許腳本。- 阻止執行所有腳本檔案,包括格式化和配置檔(.ps1xml )、模組腳本檔(.psm1 )和 PowerShell 配置檔(.ps1 )。 |
嚴格限制,適合高度安全的環境。- 防止任何腳本執行,確保系統不受未經授權的腳本影響。 |
AllSigned | 允許執行腳本。- 要求所有腳本和配置檔都必須由受信任的發行者簽署,包括您在本機電腦上編寫的腳本。- 在執行尚未被您標記為信任或不信任的發行者的腳本時,會提示您確認。- 風險:可能會執行已簽署但惡意的腳本。 | 確保所有腳本都是經過簽名的,但需要注意簽名腳本的可信度。- 適合需要執行腳本,但又希望增加安全性的環境。 |
RemoteSigned | Windows 伺服器電腦的預設執行政策。- 允許執行腳本。- 要求從網際網路下載的腳本和配置檔具有受信任發行者的數位簽章,這包括透過電子郵件和即時通訊程式收到的檔案。- 對於在本機撰寫且未從網際網路下載的腳本,不要求數位簽章。- 如果使用 Unblock-File Cmdlet 解除封鎖,未簽名的網際網路腳本也可執行。- 風險:可能會執行非網際網路來源的未簽名腳本和可能惡意的簽名腳本。 |
在安全性和便利性之間取得平衡。- 適合需要執行本機腳本且偶爾需要執行來自網際網路的受信任腳本的環境。- 需要謹慎處理從網際網路下載的腳本,確保其來源可信。 |
Unrestricted | 非 Windows 電腦的預設執行政策,且無法更改。- 未簽名的腳本可以執行。- 在執行非本機內部網路區域的腳本和配置檔前會發出警告。- 風險:可能會執行惡意腳本。 | 提供最大程度的靈活性,但安全性較低。- 適合需要自由執行各種腳本的環境,但使用者需自行承擔風險。- 注意:在無法區分 UNC 路徑和網際網路路徑的系統上,使用 UNC 路徑識別的腳本在 RemoteSigned 執行政策下可能無法執行。 |
Bypass | 沒有任何限制,不會封鎖任何內容,且無任何警告或提示。- 設計用於將 PowerShell 腳本內建於較大型的應用程式中,或 PowerShell 作為具有自身安全模型的程式基礎的配置中。 | 完全不受限制,沒有安全性防護措施。- 適合特定自動化任務或應用程式需要,但一般不建議使用。 |
Undefined | 當前範圍內未設置執行政策。- 如果所有範圍的執行政策都是 Undefined ,則有效執行政策為:Windows 用戶端為 Restricted ,Windows 伺服器為 RemoteSigned 。 |
表示未設置特定的執行政策,系統將使用預設值。- 建議明確設定執行政策以符合安全需求。 |
Default | 設置為預設執行政策。- Windows 用戶端電腦為 Restricted 。- Windows 伺服器電腦為 RemoteSigned 。 |
快速恢復到系統預設的執行政策。 |
注意事項
Unrestricted
,且無法更改。Get-ExecutionPolicy
查看當前政策,Set-ExecutionPolicy
更改政策(注意:在非 Windows 系統上,Set-ExecutionPolicy
可用但無效)。範圍(Scope) | 描述 | 存儲位置 |
---|---|---|
MachinePolicy | 由 群組原則(Group Policy)為計算機上的所有使用者設定。 | 不存儲在本地,直接由群組原則管理 |
UserPolicy | 由 群組原則 為當前使用者設定。 | 不存儲在本地,直接由群組原則管理 |
Process | 僅影響當前的 PowerShell 會話。執行策略保存在環境變數 $env:PSExecutionPolicyPreference 中。會話關閉時,該變數和其值會被刪除。 |
環境變數 $env:PSExecutionPolicyPreference |
CurrentUser | 執行策略僅影響當前使用者。存儲在註冊表的 HKEY\_CURRENT\_USER 子鍵中。 |
HKEY\_CURRENT\_USER 註冊表子鍵 |
LocalMachine | 執行策略影響當前計算機上的所有使用者。存儲在註冊表的 HKEY\_LOCAL\_MACHINE 子鍵中。 |
HKEY\_LOCAL\_MACHINE 註冊表子鍵 |
注意事項
MachinePolicy
、UserPolicy
、Process
、CurrentUser
、LocalMachine
。LocalMachine
是預設的作用域。透過 help system 直接看範例
> get-help Set-ExecutionPolicy -Examples | more
-------------- Example 1: Set an execution policy --------------
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser RemoteSigned
LocalMachine RemoteSigned
The `Set-ExecutionPolicy` cmdlet uses the ExecutionPolicy parameter to specify the `RemoteSigned` policy. The Scope parameter specifies the default scope value, `LocalMachine`. To view the execution policy settings, use the `Get-ExecutionPolicy` cmdlet with the List parameter.
依循「動詞-名詞」的命名規則,與 Parameter 之間要用空格間隔開來。
參數都以 - ( dash ) 開頭,Verb 是 Parameter 1 的參數名稱,Get 是 Parameter 1 的參數值,因為參數值內沒有包含空格或標點符號,因此不需要用引號包起來。
Module 是 Parameter 2 的參數名稱,並被賦予了兩個值:PSReadLine 以及 PowerShellGet,兩者之間以逗號隔開。
Syntax 是開關型參數( switch parameter ),不需要賦值。
get-help get-command -parameter * | grep -A 17 -B 1 Syntax
-Syntax <System.Management.Automation.SwitchParameter>
Indicates that this cmdlet gets only the following specified data about the command:
- Aliases. Gets the standard name.
- Cmdlets. Gets the syntax.
- Functions and filters. Gets the function definition.
- Scripts and applications or files. Gets the path and filename.
Required? false
Position? named
Default value False
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? false
PowerShell 別名基本上就是命令的暱稱( nickname ),可以透過 Get-Alias
去搜尋 cmdlet 的別名。
此外,PowerShell 的別名與「 Bash 中的別名 」略有不同,別名可以是一個帶有多個參數的命令捷徑,但是 PowerShell 的別名就只是命令名稱的暱稱。
> Get-Alias -Definition "Get-Process"
CommandType Name Version Source
----------- ---- ------- ------
Alias gps -> Get-Process
主要分類以下幾種類型
PowerShell 原生的內部命令,多半依循「動詞-名詞」的命名規則。
由 PowerShell 定義的函數,可能是使用者自定義,或是由模組提供的。
對現有命令的簡化名稱,方便輸入
外部命令,通常是系統中的可執行檔案( .exe, .bat 等 )
透過 Get-Command
Get-Command ping
CommandType Name Version Source
----------- ---- ------- ------
Application ping 0.0.0.0 /sbin/ping
PS /Users/kanglin/code/stackcore_repo> Get-Command nslookup
CommandType Name Version Source
----------- ---- ------- ------
Application nslookup 0.0.0.0 /usr/bin/nslookup
PS /Users/kanglin/code/stackcore_repo> Get-Command dig
CommandType Name Version Source
----------- ---- ------- ------
Application dig 0.0.0.0 /usr/bin/dig
PS /Users/kanglin/code/stackcore_repo> Get-Command get-item
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Get-Item 7.0.0.0 Microsoft.PowerShell.Management
書中提到,並不是所有的外部命令都能在 PowerShell 中順利運行,這是因為 PowerShell 的解析器( parser )有時候無法正確地解讀,而當一個外部命令有很多參數時,事情可能變得複雜,而這也是最容易看到 PowerShell 出錯的地方,針對這問題,書中也提供了一段確保命令參數能正確執行的方法:
透過將外部命令全部用變數方式儲存參數值後,透過 &
(呼叫運算子)告訴 PowerShell 執行後面的命令或腳本,無論是名稱是否符合 PowerShell 的命名規則。
$exe = "func"
$action = "new"
$language = "powershell"
$template = "HttpTrigger"
$name = "myFunc"
& $exe $action -l $language -t $template -n $name
在 PowerShell v3 以上的版本,可以在參數前加上兩個 dash 以及一個百分比符號,PowerShell 就不會試圖去解析接下來的變數值內容。
--%
一旦使用後,PowerShell 會對其後的所有內容停止解析,包括變數展開、參數解析等。
Refer - 停止剖析令牌
$name = "MyFunctionApp"
func azure functionapp list-functions --% $name
Day 5 - 使用 Provider